package com.cangxuan.backend.config;

import com.cangxuan.backend.filter.MyAuthorizationFilter;
import com.cangxuan.backend.utils.ViewUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.http.SessionCreationPolicy;
import org.springframework.security.web.SecurityFilterChain;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;

@Slf4j
@Configuration
@EnableWebSecurity      // 启用web路径的权限认证
@EnableGlobalMethodSecurity(prePostEnabled = true)  // 启用全局方法AOP安全切面，并启用前置通知
public class SecurityConfig {

    MyAuthorizationFilter myAuthorizationFilter;

    @Autowired
    public void setMyAuthorizationFilter(MyAuthorizationFilter myAuthorizationFilter) {
        this.myAuthorizationFilter = myAuthorizationFilter;
    }

    /**
     * 自定义一个安全过滤链
     *
     * @param httpSecurity
     * @return
     */
    @Bean
    public SecurityFilterChain securityFilterChain(HttpSecurity httpSecurity) throws Exception {
        return httpSecurity.authorizeRequests()
                .antMatchers("/login",
                        "/sms/send",
                        "/goods/**",
                        "/goods/get/**",
                        "/registration/get/**",
                        "/home/**",
                        "/banner/**",
                        "/market/**",
                        "/issuer/**",
                        "/series/**",
                        "/version/**",
                        "/article/**",
                        "/swagger-ui/**",
                        "/swagger-resources/**", "/v3/**")
                .permitAll()        // 排除上面的路径，让其不做身份认证
                .anyRequest().authenticated()   // 对其它路径都进行身份认证
                .and()
                .addFilterBefore(myAuthorizationFilter, UsernamePasswordAuthenticationFilter.class) // 身份认证过滤器
                .exceptionHandling().authenticationEntryPoint((request, response, authException) -> {
                    // 当身份认证未通过时执行的操作
                    log.warn("身份认证未通过，" + authException.getMessage());
                    ViewUtils.print(response, 403, "身份认证未通过，请传递有效凭证");
                })
                .and()
                .exceptionHandling().accessDeniedHandler((request, response, accessDeniedException) -> {
                    // 当前权限认证未通过时执行的操作
                    log.warn("权限认证未通过，" + accessDeniedException.getMessage());
                    ViewUtils.print(response, 403, "权限认证未通过，拒绝访问");
                })
                .and()
                .csrf().disable()       // 禁用CSRF
                .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS)     // 关闭Session
                .and()
                .build();
    }

}
